/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.GUI;

import com.Algorithm.AHP;
import com.Algorithm.Criterion;
import com.Algorithm.Promethee;
import com.Algorithm.Variant;
import com.Entity.Employee;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 *
 * @author Prezes
 */
public class RankingController implements Initializable {
    
    private Stage dialogStage;
    private List<Employee> employees;

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
    
    public void setDialogStage(Stage dialogStage) {
        this.dialogStage = dialogStage;
    }

    public void initialize() {
        final Scene scene = dialogStage.getScene();
        
        for (int i = 0; i < Criterion.NUMBER_OF_CRITERIONS; i++) 
        {
            for (int j = i + 1; j < Criterion.NUMBER_OF_CRITERIONS; j++)
            {
                final ComboBox cb = (ComboBox)scene.lookup("#matrix_" + i + "_" + j);
                ObservableList<String> preferences = FXCollections.observableArrayList( "1/9", "1/7", "1/5", "1/3", "1", "3", "5", "7", "9" ); 
                cb.setItems(preferences);
                cb.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {

                    @Override
                    public void changed(ObservableValue<? extends String> arg0, String oldValue, String newValue) {
                        String[] comboId = cb.getId().split("_");
                        int row = Integer.parseInt(comboId[1]);
                        int column = Integer.parseInt(comboId[2]);
                        TextField tf = (TextField)scene.lookup("#matrix_" + column + "_" + row);
                        if (newValue.length() > 1)
                        {
                            String[] number = newValue.split("/");
                            tf.setText(number[1]);
                        }
                        else
                        {
                            tf.setText("1/" + newValue);
                        }
                    }
                });
            }
        }
    }
    
    public double[][] getPreferenceMatrix() {
        double[][] preferenceMatrix = new double[Criterion.NUMBER_OF_CRITERIONS][Criterion.NUMBER_OF_CRITERIONS];
        Scene scene = dialogStage.getScene();
        
        for (int i = 0; i < preferenceMatrix.length; i++)
        {
            for (int j = 0; j < preferenceMatrix[i].length; j++)
            {
                if (j > i)
                {
                    ComboBox cb = (ComboBox)scene.lookup("#matrix_" + i + "_" + j);
                    preferenceMatrix[i][j] = getPreference(cb.getValue().toString());
                }
                else 
                {
                    TextField tf = (TextField)scene.lookup("#matrix_" + i + "_" + j);
                    preferenceMatrix[i][j] = getPreference(tf.getText());
                }
            }
        }
        
        return preferenceMatrix;
    }
    
    public double getPreference(String controlValue) {
        if (controlValue.length() > 1) 
        {
            String[] number = controlValue.split("/");
            return 1.0 / Double.parseDouble(number[1]);
        }
        else
        {
            return Double.parseDouble(controlValue);
        }
        
    }
    
    public double[] getWeights(double[][] preferenceMatrix) {
        double[] weights = new double[Criterion.NUMBER_OF_CRITERIONS];
        
        double totalSum = 0.0;
        for (int i = 0; i < preferenceMatrix.length; i++)
        {
            double rowSum = 0.0;
            for (int j = 0; j < preferenceMatrix[i].length; j++)
            {
                rowSum += preferenceMatrix[i][j];
            }
            totalSum += rowSum;
            weights[i] = rowSum;
        }
        
        for (int i = 0; i < weights.length; i++)
        {
            weights[i] /= totalSum;
        }
        
        return weights;
    }
    
    @FXML
    public void generateRanking(ActionEvent event) throws IOException {
        double[][] preferenceMatrix = getPreferenceMatrix();
        
        System.out.println("\nPREFERENCE MATRIX");
        for (int i = 0; i < preferenceMatrix.length; i++)
        {
            for (int j = 0; j < preferenceMatrix[i].length; j++)
            {
                System.out.printf("%7.2f", preferenceMatrix[i][j]);
            }
            System.out.print("\n");
        }
        
        double[] weights = getWeights(preferenceMatrix);
        
        System.out.println("\nCRITERION WEIGHTS");
        for (int i = 0; i < weights.length; i++)
        {
            System.out.printf("%7.2f", weights[i]);
            System.out.print("\n");
        }
        
        Promethee p = new Promethee(weights);
        p.buildModel(employees);
        List<Variant> rankingPromethee = p.determineRanking();
        
        AHP ahp = new AHP(preferenceMatrix);
        ahp.buildModel(employees);
        List<Variant> rankingAHP = ahp.determineRanking();

        printRanking("\nPROMETHEE RANKING", rankingPromethee);
    
        printRanking("\nAHP RANKING", rankingAHP);
        System.out.print("Indeks spójności = ");
        System.out.printf("%7.2f", ahp.consistencyIndex);
        
        Popup popup = new Popup();
        popup.createPopupResult(getVariantSum(rankingPromethee, rankingAHP));
        
        ExcelReport report = new ExcelReport(rankingPromethee, rankingAHP);
         
    }
   
    
    public List<Variant> getVariantSum(List<Variant> rankingPromethee, List<Variant> rankingAHP) {
        List<Variant> sum = new ArrayList<>();
        
        for (int i = 0; i < rankingPromethee.size(); i++)
        {
            for (int j = 0; j < rankingAHP.size(); j++)
            {
                if (rankingPromethee.get(i).getEmployee().getIdEmployee() == rankingAHP.get(j).getEmployee().getIdEmployee())
                {
                    double value = rankingPromethee.size() - i + rankingAHP.size() - j;
                    sum.add(new Variant(rankingPromethee.get(i).getEmployee(), value));
                }
            }
        }
        
        Collections.sort(sum);
        return sum;
    }
    
    public void printRanking(String ranking, List<Variant> variant) {
        System.out.println(ranking);
        
        for (Variant v : variant)
        {
            System.out.printf("%-30s %7.2f\n", 
                    v.getEmployee().getName() + " " + v.getEmployee().getSurname(), 
                    v.getValue());
        }
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
    }
    
}
